package com.yuandian.customer.perception.service.impl;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuandian.api.business_monitor.po.SearchParams;
import com.yuandian.api.customer_perception.po.OperatorOverviewParams;
import com.yuandian.api.customer_perception.po.OperatorResolutionParams;
import com.yuandian.api.customer_perception.vo.*;
import com.yuandian.api.management.feign.RemoteBusinessHallService;
import com.yuandian.api.management.feign.RemoteConfSystemService;
import com.yuandian.base.service.ITaskDataService;
import com.yuandian.bpm.common.core.constant.CommonConstants;
import com.yuandian.bpm.common.core.util.R;
import com.yuandian.customer.perception.mapper.OperatorResolutionMapper;
import com.yuandian.customer.perception.service.IOperatorResolutionService;
import com.yuandian.enums.TableNameEnum;
import com.yuandian.po.MergeDataConfig;
import com.yuandian.po.MergeField;
import com.yuandian.po.MultipleTableInfo;
import com.yuandian.utils.DynamicTableNameUtil;
import com.yuandian.utils.MergeDataUtil;
import com.yuandian.utils.PageDataInfo;
import com.yuandian.vo.TrendDataVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * <p> 操作员分析 service接口实现 </p>
 *
 * @Author: LinSheHi
 * @Date: 2021/8/16 10:03
 */
@Slf4j
@Service
public class OperatorResolutionServiceImpl implements IOperatorResolutionService {

    @Autowired
    private OperatorResolutionMapper operatorResolutionMapper;


    @Autowired
    private ITaskDataService taskDataService;




    @Autowired
    private RemoteConfSystemService remoteConfSystemService;

    @Autowired
    private RemoteBusinessHallService remoteBusinessHallService;

    private static final List<Integer> systemIdList = new ArrayList<>();
    private static Boolean dataStatus = false;
	
    /**
     * 获取指定 系统类型(1：营业厅 2：网厅 3：第三方接口) 下的所有系统Id
     */

    /**
     * 业务办理列表
     *
     * @param params 请求参数
     * @return 通用返回对象
     */
    @Override
    public R<Object> queryBusinessProcessList(OperatorResolutionParams params) {
        checkdataStatus();
        Page<OperatorResolutionListVo> page = new Page<>(params.getPageNum(), params.getPageSize());

		// 获取表信息集
		MultipleTableInfo info = new MultipleTableInfo();
		info.setTableName(TableNameEnum.KHGZ_BUSI_SYS_DETAIL_STAT.getName());
		List<MultipleTableInfo> visitTables = Collections.singletonList(info);

        // 查询数据
		params.setSystemIds(systemIdList);
        List<OperatorResolutionListVo> res = operatorResolutionMapper.queryBusinessProcessList(page, params, visitTables);

        return R.ok(new PageDataInfo(page,res));
    }

    /**
     * 业务办理列表下载
     *
     * @param params 请求参数
     * @return 通用返回对象
     */
    @Override
    public List<OperatorResolutionListVo> queryBusinessProcessListExport(OperatorResolutionParams params) {
        checkdataStatus();
		// 获取表信息集
		MultipleTableInfo info = new MultipleTableInfo();
		info.setTableName(TableNameEnum.KHGZ_BUSI_SYS_DETAIL_STAT.getName());
		List<MultipleTableInfo> visitTables = Collections.singletonList(info);

		params.setSystemIds(systemIdList);

        List<OperatorResolutionListVo> res = operatorResolutionMapper.queryBusinessProcessListExport(params, visitTables);

        return res;
    }


    /**
     * 业务办理详情列表
     *
     * @param params 请求参数
     * @return 通用返回对象
     */
    @Override
    public R<Object> queryBusinessProcessStatisticsList(OperatorResolutionParams params) {
        Page<OperatorStatisticsListVo> page = new Page<>(params.getPageNum(), params.getPageSize());

		// 获取表信息集
		MultipleTableInfo info = new MultipleTableInfo();
		info.setTableName(TableNameEnum.KHGZ_BUSI_SYS_DETAIL_STAT.getName());
		List<MultipleTableInfo> visitTables = Collections.singletonList(info);
        checkdataStatus();
		params.setSystemIds(systemIdList);
        List<OperatorStatisticsListVo> res = operatorResolutionMapper.queryBusinessProcessStatisticsList(page, params, visitTables);
        return R.ok(new PageDataInfo(page,res));
    }


    /**
     * 业务办理详情列表下载
     *
     * @param params 请求参数
     * @return 通用返回对象
     */
    @Override
    public List<OperatorStatisticsListVo> queryBusinessProcessStatisticsListExport(OperatorResolutionParams params) {
		// 获取表信息集
		MultipleTableInfo info = new MultipleTableInfo();
		info.setTableName(TableNameEnum.KHGZ_BUSI_SYS_DETAIL_STAT.getName());
		List<MultipleTableInfo> visitTables = Collections.singletonList(info);
        checkdataStatus();
		params.setSystemIds(systemIdList);
        List<OperatorStatisticsListVo> res = operatorResolutionMapper.queryBusinessProcessStatisticsListExport(params, visitTables);

        return res;
    }



		/**
		 * 业务办理明细列表
		 *
		 * @param params 请求参数
		 * @return 通用返回对象
		 */
    @Override
    public R<Object> queryBusinessProcessDetailList(OperatorResolutionParams params) {
        Page<OperatorBusiDetailListVo> page = new Page<>(params.getPageNum(), params.getPageSize());
		String tableName = TableNameEnum.DWS_BUSINESS_DETAIL.getName();

		List<OperatorBusiDetailListVo> resList = operatorResolutionMapper.queryBusinessProcessDetailList(page, params, tableName);

		OperatorOverviewParams p = new OperatorOverviewParams();
		p.setAreaCode(params.getAreaCode());
        R<List<SearchOptionVo>> listR = remoteBusinessHallService.queryBusinessHall(p);
        if (listR.getCode() == CommonConstants.FAIL) {
            log.error("远程调用配置系统获取获取营业厅数据失败，错误：{}", listR.getMsg());
        }
        List<SearchOptionVo> list = listR.getData();
		Map<String, String> map = new HashMap<>();

		if (!CollectionUtils.isEmpty(list)) {
			for (SearchOptionVo searchOptionVo : list) {
				map.put(searchOptionVo.getCode(), searchOptionVo.getValue());
			}
		}

		if (!CollectionUtils.isEmpty(resList)) {
			for (OperatorBusiDetailListVo detailListVo : resList) {
				if (StringUtils.isNotEmpty(detailListVo.getBusinessHallId())) {
					detailListVo.setBusinessHallName(map.get(detailListVo.getBusinessHallId()));
				}
				if (StringUtils.isNotEmpty(params.getAreaCode())) {
					detailListVo.setAreaCode(params.getAreaCode());
					detailListVo.setAreaName(params.getAreaName());
				}
			}
		}

        return R.ok(new PageDataInfo(page, resList));
    }


    /**
     * 操作员业务办理量
     *
     * @param params 请求参数
     * @return 通用返回对象
     */
    @Override
    public R<Object> queryOperatorBusinessProcessCount(OperatorResolutionParams params) {

		// 获取表信息集
		MultipleTableInfo info = new MultipleTableInfo();
		info.setTableName(TableNameEnum.KHGZ_BUSI_SYS_DETAIL_STAT.getName());
		List<MultipleTableInfo> visitTables = Collections.singletonList(info);
        checkdataStatus();
        // 2、查询数据
		params.setSystemIds(systemIdList);
        List<OperatorCompleteCountVo> res = operatorResolutionMapper.queryOperatorBusinessProcessCount(params, visitTables);
        Map<String, Object> map = new HashMap<>();
        // 3.统计数据(总办理量、总成功办理量、总失败办理量)
        int handleTotle = 0;
        int handleSuccessTotle = 0;
        int handleFailTotle = 0;
        if (res != null && res.size() > 0) {
            for (OperatorCompleteCountVo re : res) {
                handleSuccessTotle += re.getSuccessCount();
                handleFailTotle += re.getFailCount();
            }
            handleTotle = handleSuccessTotle + handleFailTotle;
        }
        map.put("handleTotle", handleTotle);
        map.put("handleSuccessTotle", handleSuccessTotle);
        map.put("handleFailTotle", handleFailTotle);
        map.put("data", res);

        return R.ok(map);
    }


    /**
     * 操作员人工操作平均耗时
     *
     * @param params 请求参数
     * @return 通用返回对象
     */
    @Override
    public R<Object> queryOperatorAvgDealTime(OperatorResolutionParams params) {

		// 获取表信息集
		MultipleTableInfo info = new MultipleTableInfo();
		info.setTableName(TableNameEnum.KHGZ_BUSI_SYS_DETAIL_STAT.getName());
		List<MultipleTableInfo> visitTables = Collections.singletonList(info);
        checkdataStatus();
		params.setSystemIds(systemIdList);
        // 耗时长列表
        params.setIsAsc("DESC");
        List<OperatorAvgDealTimeVo> longTimeBusinessList = operatorResolutionMapper.queryOperatorAvgDealTime(params, visitTables);
        // 耗时短列表
        params.setIsAsc("ASC");
        List<OperatorAvgDealTimeVo> shortTimeBusinessList = operatorResolutionMapper.queryOperatorAvgDealTime(params, visitTables);
        Map<String, Object> map = new HashMap<>();
        map.put("longTimeBusinessList", longTimeBusinessList);
        map.put("shortTimeBusinessList", shortTimeBusinessList);

        return R.ok(map);
    }


    /**
     * 操作员办理业务分布图
     *
     * @param params 请求参数
     * @return 通用返回对象
     */
    
    @Override
    public R<Object> queryOperatorBusinessPercent(OperatorResolutionParams params) {

		// 获取表信息集
		MultipleTableInfo info = new MultipleTableInfo();
		info.setTableName(TableNameEnum.KHGZ_BUSI_SYS_DETAIL_STAT.getName());
		List<MultipleTableInfo> visitTables = Collections.singletonList(info);
        checkdataStatus();
		params.setSystemIds(systemIdList);
        // 2、查询数据
        List<OperatorCompleteCountVo> res = operatorResolutionMapper.queryOperatorBusinessPercent(params, visitTables);
        // 3.统计数据(总办理量、总成功办理量、总失败办理量)
        int handleSuccessTotle = 0;
        int handleFailTotle = 0;
        OperatorCompleteCountVo operatorCompleteCountVo = new OperatorCompleteCountVo();
        // 分别展示前5项业务的成功数和失败数，后面的统一相加且业务名为 ‘其他’
        if (res != null && res.size() > 5) {
            for (int i = res.size() - 1; i > 4 ; i--) {
                OperatorCompleteCountVo completeCountVo = res.get(i);
                handleSuccessTotle += completeCountVo.getSuccessCount();
                handleFailTotle += completeCountVo.getFailCount();
                res.remove(i);
            }
            operatorCompleteCountVo.setFailCount(handleFailTotle);
            operatorCompleteCountVo.setSuccessCount(handleSuccessTotle);
            operatorCompleteCountVo.setBusinessName("其他");
            res.add(operatorCompleteCountVo);
        }

        return R.ok(res);
    }


    /**
     * 操作员办理业务告警类型
     *
     * @param params 请求参数
     * @return 通用返回对象
     */
    
    @Override
    public R<Object> queryOperatorAlarmTypeCount(OperatorResolutionParams params) {

		// 获取表信息集
		MultipleTableInfo info = new MultipleTableInfo();
		info.setTableName(TableNameEnum.MYSQL_BUSI_BASE_ALARM_STAT.getName());
		List<MultipleTableInfo> visitTables = Collections.singletonList(info);

        checkdataStatus();
		params.setSystemIds(systemIdList);
        // 2、查询数据
        List<OperatorAlarmTypeCountVo> res = operatorResolutionMapper.queryOperatorAlarmTypeCount(params, visitTables);

        return R.ok(res);
    }

    /**
     * 操作员办理业务平均耗时折线图
     *
     * @param params 请求参数
     * @return 通用返回对象
     */
    
    @Override
    public R<Object> queryOperatorBusinessAvgVisitTime(OperatorResolutionParams params) {

        // 1、获取表信息集
        MultipleTableInfo info = DynamicTableNameUtil.generalSingleTableNamesFromTimeRange(
                params.getStartTime(),
                params.getEndTime());
        // 2、校验表是否存在，剔除不存在的表
		List<String> tableNameList = Collections.singletonList(TableNameEnum.KHGZ_BUSI_SYS_DETAIL_STAT.getName());
        checkdataStatus();
        // 3、设置表名、时间范围矫正
        params.setTableNameList(tableNameList);
        params.setSystemIds(systemIdList);

        List<OperatorLineVo> res = operatorResolutionMapper.queryOperatorBusinessAvgVisitTime(params);

        // 5、归并数据
        Integer minScale = DynamicTableNameUtil.getMinScaleByTableType(info.getTableType());
        Integer scale = null;
        if (params.getScale() != null) {
            scale = DynamicTableNameUtil.getScaleByMinScaleAndParam(minScale, params.getScale());
        }
        List<MergeField> mergeFieldList = new ArrayList<>();
        mergeFieldList.add(new MergeField("totalVisitTime"));
        mergeFieldList.add(new MergeField("visitCount"));
        Map<String, Object> map = MergeDataUtil.mergeData(new MergeDataConfig.Builder(
                OperatorLineVo.class,
                res,
                params.getStartTime(),
                params.getEndTime(),
                mergeFieldList)
                .cycleTimeKey("labelTime")
                .labelTimeFormatter("MM-dd'\n'HH:mm")
                .scale(scale)
                .build());

        map.put("minScale", minScale);

        Map<String, List<Double>> resFieldMap = (Map<String, List<Double>>) map.get("resFieldMap");
        List<Double> totalVisitTimeList = resFieldMap.get("totalVisitTimeList");
        List<Double> visitCountList = resFieldMap.get("visitCountList");
        List<Double> list = new ArrayList<>();
        for (int i = 0; i < totalVisitTimeList.size(); i++) {
            double avgVisitTime = totalVisitTimeList.get(i) == 0.0 || visitCountList.get(i) == 0.0 ? 0.0 : totalVisitTimeList.get(i) / 1000 / visitCountList.get(i);
             list.add(Double.valueOf(String.format("%.2f", avgVisitTime)));
        }
        resFieldMap.put("avgVisitTimeList", list);
        // 6、重新构建趋势图结果对象
        TrendDataVo trendDataVo = taskDataService.getTrendObject(
                "KHGZ-详单分钟统计",
                params.getStartTime(),
                params.getEndTime(),
                map);
        return R.ok(trendDataVo);

    }

    /**
     * 操作员办理X业务趋势图
     *
     * @param params 请求参数
     * @return 通用返回对象
     */
    
    @Override
    public R<Object> queryOperatorBusinessLine(OperatorResolutionParams params) {
        checkdataStatus();
        // 1、获取表信息集
        MultipleTableInfo info = DynamicTableNameUtil.generalSingleTableNamesFromTimeRange(
                params.getStartTime(),
                params.getEndTime());
        // 2、校验表是否存在，剔除不存在的表
		List<String> tableNameList = Collections.singletonList(TableNameEnum.KHGZ_BUSI_SYS_DETAIL_STAT.getName());

        // 3、设置表名、时间范围矫正
        params.setTableNameList(tableNameList);
        params.setSystemIds(systemIdList);

        // 2、查询数据
        List<OperatorLineVo> res = operatorResolutionMapper.queryOperatorBusinessLine(params);


        // 5、归并数据
        Integer minScale = DynamicTableNameUtil.getMinScaleByTableType(info.getTableType());
        Integer scale = null;
        if (params.getScale() != null) {
            scale = DynamicTableNameUtil.getScaleByMinScaleAndParam(minScale, params.getScale());
        }
        List<MergeField> mergeFieldList = new ArrayList<>();
        mergeFieldList.add(new MergeField("visitCount"));
        mergeFieldList.add(new MergeField("completeCount"));
        mergeFieldList.add(new MergeField("failCount"));
        mergeFieldList.add(new MergeField("alarmCount"));
        Map<String, Object> map = MergeDataUtil.mergeData(new MergeDataConfig.Builder(
                OperatorLineVo.class,
                res,
                params.getStartTime(),
                params.getEndTime(),
                mergeFieldList)
                .cycleTimeKey("labelTime")
                .labelTimeFormatter("MM-dd'\n'HH:mm")
                .scale(scale)
                .build());
        map.put("minScale", minScale);
        // 6、重新构建趋势图结果对象
        TrendDataVo trendDataVo = taskDataService.getTrendObject(
                "KHGZ-详单分钟统计",
                params.getStartTime(),
                params.getEndTime(),
                map);

        return R.ok(trendDataVo);
    }

    /**
     * 根据查询条件查询某业务员操作过的所有系统
     *
     * @param params 请求参数
     * @return 通用返回对象
     */
    
    @Override
    public R<Object> querySystemListByOperator(OperatorResolutionParams params) {
        checkdataStatus();
		// 获取表信息集
		MultipleTableInfo info = new MultipleTableInfo();
		info.setTableName(TableNameEnum.KHGZ_BUSI_SYS_DETAIL_STAT.getName());
		List<MultipleTableInfo> visitTables = Collections.singletonList(info);

		params.setSystemIds(systemIdList);
        // 2、查询数据
        List<Map<Integer, String>> res = operatorResolutionMapper.querySystemListByOperator(params, visitTables);

        return R.ok(res);
    }

    /**
     * 根据查询条件查询某业务员操作过的所有业务
     *
     * @param params 请求参数
     * @return 通用返回对象
     */
    @Override
    public R<Object> queryBusinessListByOperator(OperatorResolutionParams params) {
        checkdataStatus();
		// 获取表信息集
		MultipleTableInfo info = new MultipleTableInfo();
		info.setTableName(TableNameEnum.KHGZ_BUSI_SYS_DETAIL_STAT.getName());
		List<MultipleTableInfo> visitTables = Collections.singletonList(info);

		params.setSystemIds(systemIdList);
        // 2、查询数据
        List<Map<String, String>> res = operatorResolutionMapper.queryBusinessListByOperator(params, visitTables);

        return R.ok(res);
    }

    private void checkdataStatus(){
        if (!dataStatus){
            SearchParams params = new SearchParams();
            params.setType(1);
            R<List<SearchOptionVo>> listR = remoteConfSystemService.queryDefaultAppSystemOptions(params);
            if (listR.getCode() == CommonConstants.FAIL) {
                log.error("远程调用配置系统获取获取系统配置数据失败，错误：{}", listR.getMsg());
            }
            List<SearchOptionVo> list = listR.getData();
            for (SearchOptionVo searchOptionVo : list) {
                systemIdList.add(searchOptionVo.getId());
            }
        }
        dataStatus = true;
    }
}
